import { useEffect, useRef, useState, useCallback, useMemo } from 'react';
import { observer } from '@formily/react';
import { message } from 'antd';
import { useApp, h5Utils, useEvents } from '@inbiz/utils';
import CardType from './components/ColorCardType';
import PureType from './components/PureType';
import SimpleType from './components/SimpleType';
import CenterIndex from './components/CenterIndex';
import EasyType from './components/EasyType';
import { saveProcessGroup } from './service';
import type { ProcessCenterProps } from './types';
import {
  puredynamicdata as puredynamicdataDefault,
  colordynamicdata as colordynamicdataDefault,
  simpledynamicdata as simpledynamicdataDefault,
  tabdynamicdata as tabdynamicdataDefault,
  easydynamicdata as easydynamicdataDefault,
} from '../../designer/schema';
import {
  getApplyList as oldgetApplyList,
  getApplyCategory as oldgetApplyCategory,
  getToMe as oldgetToMe,
  getMyToDo as oldgetMyToDo,
  getMyApply as oldgetMyApply,
  getHaveDone as oldgetHaveDone,
  getDraft as oldgetDraft,
  getClassification as oldgetClassification,
  getProcessCenterNumber as oldgetProcessCenterNumber,
} from './service';
import './style.less';

export const ProcessCenter = observer((props: ProcessCenterProps) => {
  const {
    viewtype,
    puredynamicdata = puredynamicdataDefault,
    colordynamicdata = colordynamicdataDefault,
    simpledynamicdata = simpledynamicdataDefault,
    tabdynamicdata = tabdynamicdataDefault,
    easydynamicdata = easydynamicdataDefault,
    inbiz,
    defaultpage,
    showTabTitle,
    rangeConfig,
    ifQuickApproval,
    processGroup = {
      groupGuid: '',
    },
    openMode = 'newPage',
    openPopUpHeight = {
      value: '600',
      type: 'px',
    },
    openPopUpWidth = {
      value: '1000',
      type: 'px',
    },
    drawerWidth = {
      value: '60',
      type: '%',
    },
    callBackEvents,
    emit,
    customClickItem,
  } = props;

  const [configEvents] = useEvents(callBackEvents, emit);
  const processRef = useRef({ getCategory: Function, searchApply: Function });
  const easyRef = useRef({ getGroupData: Function, getProcessData: Function });
  const [isChange, $isChange] = useState(1);
  const appInfo = useApp();
  const { userInfoByToken, userInfo } = inbiz.appInfo;
  const _userInfo = userInfoByToken || appInfo.userInfoByToken || { ID: userInfo?.guid };

  const newPureDynamicdata = useMemo(() => {
    return puredynamicdata ? puredynamicdata.filter((item: { hide: any }) => !item.hide) : [];
  }, [puredynamicdata]);

  const newColorDynamicdata = useMemo(() => {
    return colordynamicdata ? colordynamicdata.filter((item: { hide: any }) => !item.hide) : [];
  }, [colordynamicdata]);

  const newSimpleDynamicdata = useMemo(() => {
    return simpledynamicdata ? simpledynamicdata.filter((item: { hide: any }) => !item.hide) : [];
  }, [simpledynamicdata]);

  const newtabdynamicdata = useMemo(() => {
    return tabdynamicdata ? tabdynamicdata.filter((item: { hide: any }) => !item.hide) : [];
  }, [tabdynamicdata]);

  const easyDynamicData = useMemo(() => {
    const nowList = easydynamicdata.length > 0 ? easydynamicdata : easydynamicdataDefault;
    return easydynamicdata ? nowList.filter((item: { hide: any }) => !item.hide) : [];
  }, [easydynamicdata]);

  const getProcessCenterNumber = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onNumberParams?.(params)) || params;
    const data = await (configEvents.current?.onNumberRequest || oldgetProcessCenterNumber)(newParams as any)
    return await configEvents.current?.onNumberData?.(data) || data
  }, []);

  const getApplyCategory = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onCategoryParams?.(params)) || params;
    const data = await (configEvents.current?.onCategoryRequest || oldgetApplyCategory)(newParams as any);
    return await configEvents.current?.onCategoryData?.(data) || data;
  }, []);

  const getGroup = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onGroupParams?.(params)) || params;
    const data = await (configEvents.current?.onGroupRequest || oldgetApplyCategory)(newParams as any);
    return await configEvents.current?.onGroupData?.(data) || data;
  }, []);

  const getApplyList = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onApplyParams?.(params)) || params;
    const data = await (configEvents.current?.onApplyRequest || oldgetApplyList)(newParams as any);
    return await configEvents.current?.onApplyData?.(data) || data;
  }, []);

  const getMyToDo = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onTodoParams?.(params)) || params;
    const data = await (configEvents.current?.onTodoRequest || oldgetMyToDo)(newParams as any);
    return await configEvents.current?.onTodoData?.(data) || data;
  }, []);

  const getApplying = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onApplyingParams?.(params)) || params;
    const data = await (configEvents.current?.onApplyingRequest || oldgetMyApply)(newParams as any);
    return await configEvents.current?.onApplyingData?.(data) || data;
  }, []);

  const getDraft = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onDraftParams?.(params)) || params;
    const data = await (configEvents.current?.onDraftRequest || oldgetDraft)(newParams as any);
    return await configEvents.current?.onDraftData?.(data) || data;
  }, []);

  const getToMe = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onCctomeParams?.(params)) || params;
    const data = await (configEvents.current?.onCctomeRequest || oldgetToMe)(newParams as any);
    return await configEvents.current?.onCctomeData?.(data) || data;
  }, []);

  const getMyApply = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onMyApplyParams?.(params)) || params;
    const data = await (configEvents.current?.onMyApplyRequest || oldgetMyApply)(newParams as any);
    return await configEvents.current?.onMyApplyData?.(data) || data;
  }, []);

  const getHaveDone = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onMyCompleteParams?.(params)) || params;
    const data = await (configEvents.current?.onMyCompleteRequest || oldgetHaveDone)(newParams as any);
    return await configEvents.current?.onMyCompleteData?.(data) || data;
  }, []);

  const getClassification = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onMyArchiveParams?.(params)) || params;
    const data = await (configEvents.current?.onMyArchiveRequest || oldgetClassification)(newParams as any);
    return await configEvents.current?.onMyArchiveData?.(data) || data;
  }, []);

  const reaquestProps = {
    getProcessCenterNumber,
    getApplyCategory,
    getApplyList,
    getMyToDo,
    getApplying,
    getDraft,
    getToMe,
    getMyApply,
    getHaveDone,
    getClassification,
    getGroup,
    configEvents,
  };

  const saveProcessGroupData = () => {
    const needSaveProcessGroup = localStorage.getItem('needSaveProcessGroup');
    if (needSaveProcessGroup == '1' && rangeConfig == 'custom') {
      const groupIds =
        processGroup.selectedRows
          .map((item: { value: any; id: any }) => item.value || item.id)
          .join() || '-1';
      saveProcessGroup({
        key: processGroup?.groupGuid ?? '',
        groupIds,
      }).then((res) => {
        if (res.code == '200') {
          localStorage.setItem('needSaveProcessGroup', '0');
          if (viewtype == 'processTable') {
            processRef?.current?.getCategory();
            processRef?.current?.searchApply();
          }
          if (viewtype == 'easy') {
            easyRef?.current?.getGroupData();
            easyRef?.current?.getProcessData();
          }
          $isChange(Math.random());
        } else {
          message.error(res.message);
        }
      });
    }
  };

  useEffect(() => {
    h5Utils.inbizPageEvent.off('pageSave');
    h5Utils.inbizPageEvent.on('pageSave', () => {
      saveProcessGroupData();
    });
    return () => {
      h5Utils.inbizPageEvent.off('pageSave');
    };
  }, [saveProcessGroupData, viewtype]);

  return (
    <div className={'inbiz-ProcessCenter'}>
      {viewtype == 'pure' && (
        <PureType
          {...props}
          {...reaquestProps}
          dynamicdata={newPureDynamicdata}
          userInfo={_userInfo}
          isChange={isChange}
        />
      )}
      {viewtype == 'colorcard' && (
        <CardType
          {...props}
          {...reaquestProps}
          dynamicdata={newColorDynamicdata}
          userInfo={_userInfo}
          isChange={isChange}
        />
      )}
      {viewtype == 'simple' && (
        <SimpleType
          {...props}
          {...reaquestProps}
          dynamicdata={newSimpleDynamicdata}
          userInfo={_userInfo}
          isChange={isChange}
        />
      )}
      {viewtype == 'processTable' && (
        <CenterIndex
          {...reaquestProps}
          userInfo={_userInfo}
          tabsArr={newtabdynamicdata}
          showTabTitle={showTabTitle}
          defaultpage={defaultpage}
          rangeConfig={rangeConfig}
          processGroup={processGroup}
          ref={processRef}
          openMode={openMode}
          openPopUpHeight={openPopUpHeight}
          openPopUpWidth={openPopUpWidth}
          drawerWidth={drawerWidth}
          ifQuickApproval={ifQuickApproval}
          customClickItem={customClickItem}
        />
      )}
      {viewtype == 'easy' && (
        <EasyType
          {...props}
          {...reaquestProps}
          dynamicdata={easyDynamicData}
          userInfo={_userInfo}
          ref={easyRef}
          customClickItem={customClickItem}
        />
      )}
    </div>
  );
});

export default ProcessCenter;
